/*
 * Copyright 2008. Mount Sinai Hospital, Toronto, Canada.
 * 
 * Licensed under the Apache License, Version 2.0. You
 * can find a copy of the license at:
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * IN NO EVENT SHALL MOUNT SINAI HOSPITAL BE LIABLE TO ANY PARTY FOR DIRECT, 
 * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST 
 * PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, 
 * EVEN IF MOUNT SINAI HOSPITAL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
 * DAMAGE.
 * 
 * MOUNT SINAI HOSPITAL SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND 
 * ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". 
 * MOUNT SINAI HOSPITAL HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, 
 * UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 
 */

package com.sinai.mshab.extensions.search;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Random;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.SourcesTableEvents;
import com.google.gwt.user.client.ui.TableListener;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.widgetideas.table.client.CachedTableModel;
import com.google.gwt.widgetideas.table.client.FixedWidthFlexTable;
import com.google.gwt.widgetideas.table.client.FixedWidthGrid;
import com.google.gwt.widgetideas.table.client.PagingOptions;
import com.google.gwt.widgetideas.table.client.PagingScrollTable;
import com.google.gwt.widgetideas.table.client.ReadOnlyTableModel;
import com.google.gwt.widgetideas.table.client.RowPagingListener;
import com.google.gwt.widgetideas.table.client.ScrollTable;
import com.google.gwt.widgetideas.table.client.SelectionGrid;
import com.google.gwt.widgetideas.table.client.SourceTableSelectionEvents;
import com.google.gwt.widgetideas.table.client.TableSelectionListener;
import com.google.gwt.widgetideas.table.client.overrides.FlexTable.FlexCellFormatter;
import com.sinai.mshab.format.util.Observable;
import com.sinai.mshab.format.util.Observer;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class ResultsGrid extends VerticalPanel implements Observable {

	private ArrayList<String> columnNames = new ArrayList<String>();

	private final FixedWidthGrid dataTable;

	private ArrayList<Observer> observers = new ArrayList<Observer>();

	private String state = "";

	/**
	 * A custom {@link ReadOnlyTableModel} that generates random data. We are
	 * using a {@link CachedTableModel}, so a request will only arrive if the
	 * current page isn't cached.
	 */
	//TODO: fix later.
//	private class MyTableModel extends ReadOnlyTableModel {
//
//		private int startRow, numRows;
//		private Request request;
//		private Callback callback;
//
//		@Override
//		public void requestRows(Request request, Callback callback) {
//
//			// save our params
//			this.startRow = request.getStartRow();
//			this.numRows = request.getNumRows();
//			this.request = request;
//			this.callback = callback;
//
//			// TODO: make an RPC for the data.
//			String results[][] =
//					{ { "1", "Hmm", "Hey" }, { "2", "Hmm", "Hey" },
//							{ "3", "Hmm", "Hey" }, { "4", "Hmm", "Hey" },
//							{ "5", "Hmm", "Hey" }, { "6", "Hmm", "Hey" },
//							{ "7", "Hmm", "Hey" }, { "8", "Hmm", "Hey" },
//							{ "9", "Hmm", "Hey" }, { "10", "Hmm", "Hey" },
//							{ "11", "Hmm", "Hey" }, { "12", "Hmm", "Hey" },
//							{ "13", "Hmm", "Hey" }, { "14", "Hmm", "Hey" },
//							{ "15", "Hmm", "Hey" }, { "16", "Hmm", "Hey" },
//							{ "17", "Hmm", "Hey" }, { "18", "Hmm", "Hey" },
//							{ "19", "Hmm", "Hey" }, { "20", "Hmm", "Hey" },
//							{ "21", "Hmm", "Hey" } };
//			fillTable(results);
//		}
//
//		public void fillTable(String[][] data) {
//			Collection<Collection<Serializable>> rows =
//					new ArrayList<Collection<Serializable>>();
//			for (int i = 0; i < data.length; i++) {
//				// Create a list of cell data
//				List<Serializable> cells = new ArrayList<Serializable>();
//				for (int j = 0; j < data[0].length; j++) {
//					cells.add(data[i][j]);
//				}
//				rows.add(cells);
//			}
//
//			// Make the callback
//			Response response = new SerializableResponse(rows);
//			callback.onRowsReady(request, response);
//		}
//	}

	public ResultsGrid() {
		dataTable = null;
	}
	
/*	public ResultsGrid(ArrayList<String> columns) {

		setStyleName("mshab-SearchGrid");
		columnNames = columns;

		// Get the components of the ScrollTable
		FixedWidthFlexTable headerTable = createHeaderTable();
		dataTable = createDataTable();

		// Setup the table model
		// TODO: RPC over to find this information.
		MyTableModel tableModel = new MyTableModel();
		tableModel.setRowCount(21);
		CachedTableModel cachedModel = new CachedTableModel(tableModel);
		cachedModel.setPostCachedRowCount(15);
		cachedModel.setPostCachedRowCount(30);

		// Combine the components into a ScrollTable
		final PagingScrollTable scrollTable =
				new PagingScrollTable(cachedModel, dataTable, headerTable);
		scrollTable.setPageSize(15);
		scrollTable.setScrollPolicy(ScrollTable.ScrollPolicy.HORIZONTAL);
		dataTable.setCellPadding(4);
		dataTable.setCellSpacing(0);
		dataTable.setWidth("700px");

		// get a click listener in place
		dataTable.addTableSelectionListener(new MyTableSelectionListner());
		dataTable.addTableListener(new MyOtherTableListener());

		// Set some options in the scroll table
		for (int i = 0; i < columns.size(); i++) {
			int width = (int) (700.0 / columns.size());
			scrollTable.setGuaranteedColumnWidth(i, width);
			System.out.println("Setting columns to width=" + width);
		}
		scrollTable.setSortingEnabled(false);

		// TODO: find out why this doesn't work.
		// scrollTable.setAutoFitEnabled(false);

		// Create some paging options
		PagingOptions options = new PagingOptions(scrollTable);

		// Add the components to the page
		add(scrollTable);
		add(options);
	}*/

	/**
	 * Create the data table.
	 * 
	 * @return a data table
	 */
	private FixedWidthGrid createDataTable() {
		// Create a new table
		FixedWidthGrid dataTable = new FixedWidthGrid();

		// Set some options in the data table
		dataTable.setSelectionPolicy(SelectionGrid.SelectionPolicy.MULTI_ROW);

		// Return the data table
		return dataTable;
	}

	private FixedWidthFlexTable createHeaderTable() {
		// Create a new table
		FixedWidthFlexTable headerTable = new FixedWidthFlexTable();

		// Level 3 headers
		for (int i = 0; i < columnNames.size(); i++) {
			headerTable.setHTML(0, i, columnNames.get(i));
		}
		return headerTable;
	}

	/**
	 * This class helps the row highlighting for the grid.
	 * 
	 * @author serge
	 * 
	 */
	private class MyTableSelectionListner implements TableSelectionListener {

		public void onAllRowsDeselected(SourceTableSelectionEvents sender) {
			System.out.println("onAllRowsDeselected");
		}

		public void onCellHover(SourceTableSelectionEvents sender, int row,
				int cell) {
		}

		public void onCellUnhover(SourceTableSelectionEvents sender, int row,
				int cell) {
		}

		public void onRowDeselected(SourceTableSelectionEvents sender, int row) {

		}

		public void onRowHover(SourceTableSelectionEvents sender, int row) {
			dataTable.getRowFormatter().addStyleName(row, "selected_row");
		}

		public void onRowUnhover(SourceTableSelectionEvents sender, int row) {
			dataTable.getRowFormatter().removeStyleName(row, "selected_row");
		}

		public void onRowsSelected(SourceTableSelectionEvents sender,
				int firstRow, int numRows) {
			System.out.println("onCellUnhover firstRow=" + firstRow
					+ " numRows=" + numRows);
		}
	}

	/**
	 * This class tells us what the user clicked on.
	 * 
	 * @author serge
	 */
	private class MyOtherTableListener implements TableListener {

		public void onCellClicked(SourcesTableEvents sender, int row, int cell) {
			String value = dataTable.getText(row, cell);
			System.out.println("onCellClicked row=" + row + " cell=" + cell
					+ " value clicked on = " + value);
			state = dataTable.getText(row, 0);
			notifyObservers();
		}
	}

	public void addObserver(Observer o) {
		observers.add(o);
	}

	public void notifyObservers() {
		for (int i = 0; i < observers.size(); i++) {
			observers.get(i).update(this, state);
		}
	}

	public int countObservers() {
		return observers.size();
	}

	public void deleteObserver(Observer observer) {
		observers.remove(observer);
	}

	public void deleteObservers() {
		observers.clear();
	}
}
